//
//   Copyright 2011 Gynvael Coldwind & Mateusz "j00ru" Jurczyk
//
//   Licensed under the Apache License, Version 2.0 (the "License");
//   you may not use this file except in compliance with the License.
//   You may obtain a copy of the License at
//
//       http://www.apache.org/licenses/LICENSE-2.0
//
//   Unless required by applicable law or agreed to in writing, software
//   distributed under the License is distributed on an "AS IS" BASIS,
//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//   See the License for the specific language governing permissions and
//   limitations under the License.
//
#pragma once
#include <stdint.h>
#include <vector>
#include "object.h"
#include "j00ru.h"
using namespace std;

enum EVENT_TYPE
{
  EVENT_PLAYER_SET_XY,
  EVENT_CREATE_OBJECT,
  EVENT_MODIFY_TILE,
  EVENT_MODIFY_PARAMS
};

typedef struct tagEVENT_PLAYER_SET_XY_STRUCT
{
  int id;           // player id
  float x, y;       // player coords
  int map;          // player map
  unsigned int pos; // player direction
} EVENT_PLAYER_SET_XY_STRUCT;

typedef struct tagEVENT_MODIFY_TILE
{
  int x, y;
  int map;
  TILE_STRUCT tile;
} EVENT_MODIFY_TILE_STRUCT;

typedef struct tagEVENT_MODIFY_PARAMS
{
  int index;
  int paramNo;
  int value;
} EVENT_MODIFY_PARAMS_STRUCT;

typedef struct tagEVENT_STRUCT
{
  enum EVENT_TYPE type;
  int tick;

  union
  {
    EVENT_PLAYER_SET_XY_STRUCT playerSetXY;
    OBJECT_STRUCT              createObject;
    EVENT_MODIFY_TILE_STRUCT   modifyTile;
    EVENT_MODIFY_PARAMS_STRUCT modifyParams;
  } u;

} EVENT_STRUCT;

typedef struct tagTRACK_STRUCT
{
  vector<EVENT_STRUCT*> events;
  int currentlyPlayedEvent;
} TRACK_STRUCT;

typedef struct tagRECORDER_STRUCT
{
  // 
  // Initial information about the game state
  //
#define PARAMETRIZED_OBJECT_COUNT 100
  int objectParams[PARAMETRIZED_OBJECT_COUNT][3];
  vector<EVENT_STRUCT*> initialState;
  
  // Already registered events (in tracks)
  vector<TRACK_STRUCT*> tracks;

  // Currently recorded track
  vector<EVENT_STRUCT*> currTrack;
  
  int startTick;
} RECORDER_STRUCT;


// Public functions
void rec_Reset(RECORDER_STRUCT* recorder);
void rec_Clean(RECORDER_STRUCT* recorder);
void rec_SaveCurrentTrack(RECORDER_STRUCT* recorder);

void rec_Insert(RECORDER_STRUCT* recorder, EVENT_STRUCT* event);
void rec_InsertCurrentPlayer(RECORDER_STRUCT* recorder);
void rec_InsertModifyTile(RECORDER_STRUCT* recorder, int x, int y, int map, TILE_STRUCT* tile);
void rec_InsertModifyParams(RECORDER_STRUCT* recorder, int index, int paramNo, int value);

void rec_MakeSnapshot(RECORDER_STRUCT* recorder);
void rec_RestoreInitState(RECORDER_STRUCT* recorder);

void rec_PlayAvailableObjects(RECORDER_STRUCT* recorder);

